package com.hb.trade.api.routine.controller.center.sys;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hb.core.pojo.center.sys.entity.DicCode;
import com.hb.core.pojo.center.sys.entity.DicType;
import com.hb.core.pojo.center.sys.entity.DistrictInfo;
import com.hb.core.pojo.parent.PageResult;
import com.hb.trade.client.center.DictionaryClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.fzzn.core.component.treebuilder.util.TreeUtil;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.LayuiResponseDto;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.util.Enums;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Comparator;
import java.util.List;
import java.util.Set;

@Slf4j
@Version(1.0)
@Api(tags = {"字典数据(包括类型和地区)接口"})
@RequestMapping("/{version}")
@RestController
public class ApiDictionaryController {

    protected final DictionaryClient dictionaryClient;

    public ApiDictionaryController(DictionaryClient dictionaryClient) {
        this.dictionaryClient = dictionaryClient;
    }

    /* ====================== dicCode 字典数据相关操作 start ====================== */
    @ApiOperation(value = "字典数据列表(返回数组)", notes = "字典数据列表(返回数组)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "typeId", value = "字典类型ID", dataTypeClass = Long.class),
    })
    @PostMapping("/dicCode/listDicCodes")
    public ResponseDto listDicCodes(@RequestBody DicCode dicCode) {
        Message<List<DicCode>> dicCodeMsg = dictionaryClient.listDicCodes(dicCode);
        return ResultUtil.msg(dicCodeMsg);
    }

    @ApiOperation(value = "字典数据列表(返回分页对象)", notes = "字典数据列表(返回分页对象)")
    @PostMapping("/dicCode/pageDicCodes")
    public ResponseDto pageDicCodes(@RequestBody DicCode dicCode) {
        Message<PageResult<DicCode>> page = dictionaryClient.pageDicCodes(dicCode);
        return ResultUtil.msg(page);
    }

    @PostMapping("/dicCode/layui/table/pageDicCodes")
    public LayuiResponseDto layuiTablePageDicCodes(@RequestBody DicCode dicCode) {
        Message<PageResult<DicCode>> page = dictionaryClient.pageDicCodes(dicCode);
        return ResultUtil.layData(0, page.getMessage(), page.getData().getTotal(), page.getData().getRecords());
    }

    @ApiOperation(value = "新增或更新字典数据", notes = "新增或更新字典数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "父级ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "typeId", value = "字典类型ID", required = true, dataTypeClass = Long.class),
            @ApiImplicitParam(name = "dicValue", value = "字典值(比如: 1, 2, 3)", required = true, dataTypeClass = String.class),
            @ApiImplicitParam(name = "dicLabel", value = "字典显示名称(比如: 工程, 货物, 服务)", required = true, dataTypeClass = String.class)
    })
    @PostMapping("/dicCode/updateDicCode")
    public ResponseDto updateDicCode(@RequestBody DicCode dicCode) {
        Message<Boolean> flag = dictionaryClient.updateDicCode(dicCode);
        return ResultUtil.msg(flag);
    }

    @ApiOperation(value = "批量删除字典数据", notes = "批量删除字典数据(如果有父子级关系的需要传所有的ID)")
    @PostMapping("/dicCode/deleteDicCodes")
    public ResponseDto deleteDicCodes(@RequestBody List<Long> ids) {
        Message<Boolean> flag = dictionaryClient.deleteDicCodes(ids);
        return ResultUtil.msg(flag);
    }


    /* ====================== dicType 字典类型相关操作 start ====================== */
    @ApiOperation(value = "字典类型列表(返回分页对象)", notes = "字典类型列表(返回分页对象)")
    @PostMapping("/dicType/pageDicTypes")
    public ResponseDto pageDicTypes(@RequestBody DicType dicType) {
        Message<PageResult<DicType>> page = dictionaryClient.pageDicTypes(dicType);
        return ResultUtil.msg(page);
    }

    @ApiOperation(value = "字典类型列表(返回数组)", notes = "字典类型列表(返回数组)")
    @PostMapping("/dicType/listDicTypes")
    public ResponseDto listDicTypes(@RequestBody DicType dicType) {
        Message<List<DicType>> list = dictionaryClient.listDicTypes(dicType);
        return ResultUtil.msg(list);
    }

    @ApiOperation(value = "新增或更新字典类型", notes = "新增或更新字典类型")
    @PostMapping("/dicType/updateDicType")
    public ResponseDto updateDicType(@RequestBody DicType dicType) {
        Message<Boolean> flag = dictionaryClient.updateDicType(dicType);
        return ResultUtil.msg(flag);
    }

    @ApiOperation(value = "批量删除字典类型", notes = "批量删除字典类型", httpMethod = "POST")
    @PostMapping("/dicType/deleteDicTypes")
    public ResponseDto deleteDicTypes(@RequestBody List<Long> ids) {
        Message<Boolean> flag = dictionaryClient.deleteDicTypes(ids);
        return ResultUtil.msg(flag);
    }

    /* ====================== 地区相关操作 其他操作 start ====================== */
    @ApiOperation(value = "地区信息列表(返回数组)", notes = "地区信息列表(返回数组)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "父级ID", dataTypeClass = Long.class),
    })
    @PostMapping("/districtInfo/listDistricts")
    public ResponseDto listDistricts(@RequestBody DistrictInfo districtInfo) {
        Message<List<DistrictInfo>> list = dictionaryClient.listDistricts(districtInfo);
        return ResultUtil.msg(list);
    }

    @ApiOperation(value = "地区信息列表(返回树形结构)", notes = "地区信息列表(返回树形结构)", httpMethod = "POST")
    @PostMapping("/districtInfo/treeDistricts")
    public ResponseDto treeDistricts() {
        Message<List<DistrictInfo>> list = dictionaryClient.listDistricts(new DistrictInfo());
        List<DistrictInfo> data = list.getData();
        JSONArray tree = TreeUtil.getTree(data, MapUtil.of("title", "disName"), false);
        return ResultUtil.msg(true, tree);
    }

    @ApiOperation(value = "地区信息列表(返回分页对象)", notes = "地区信息列表(返回分页对象)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "父级ID", dataTypeClass = Long.class),
    })
    @PostMapping("/districtInfo/pageDistrict")
    public ResponseDto pageDistrict(@RequestBody DistrictInfo districtInfo) {
        Message<PageResult<DistrictInfo>> page = dictionaryClient.pageDistrict(districtInfo);
        return ResultUtil.msg(page);
    }

    @PostMapping("/districtInfo/updateDistrictInfo")
    @ApiOperation(value = "新增或更新地区信息", notes = "新增或更新地区信息")
    public ResponseDto updateDistrictInfo(@RequestBody DistrictInfo districtInfo) {
        Message<Boolean> result = dictionaryClient.updateDistrictInfo(districtInfo);
        return ResultUtil.msg(result);
    }

    @PostMapping("/districtInfo/deleteDistrict")
    @ApiOperation(value = "删除指定的地区数据", notes = "删除指定的地区数据(不支持批量删除)")
    public ResponseDto deleteDistrict(@RequestBody DistrictInfo districtInfo) {
        Message<Boolean> result = dictionaryClient.deleteDistrict(districtInfo);
        return ResultUtil.msg(result);
    }

    @PostMapping("/districtInfo/deleteDistricts")
    @ApiOperation(value = "删除指定的地区数据", notes = "可以批量删除")
    public ResponseDto deleteDistricts(@RequestBody List<Long> ids) {
        Message<Boolean> result = dictionaryClient.deleteDistricts(ids);
        return ResultUtil.msg(result);
    }

    /* ====================== common 其他操作 start ====================== */

    @PostMapping("/enum/dicts")
    @ApiOperation(value = "获取枚举的值", notes = "获取枚举的值, 系统中所有枚举的实际值")
    public ResponseDto enumDicts(String enumName) {
        // 系统中所有的枚举类的包
        String[] packages = {
                "com.hb.core.pojo.enums",
                "com.hb.core.pojo.project.proj.enums"
        };

        List<Class<?>> classList = CollUtil.list(false);

        for (String aPackage : packages) {
            Set<Class<?>> classes = ClassUtil.scanPackage(aPackage);
            classList.addAll(classes);
        }

        if (StrUtil.isEmpty(enumName)) {
            List<Class<?>> sortList = CollUtil.sort(classList, Comparator.comparing(Class::getName));
            return ResultUtil.msg(true, sortList);
        }
        for (Class<?> clazz : classList) {
            String className = clazz.getName();

            if (className.endsWith(enumName)) {
                JSON values = Enums.listValues(className, 1);
                return ResultUtil.msg(true, values);
            }
        }
        return ResultUtil.msg(MsgEnum.NULL_RESULT);
    }

    @RequestMapping("/enum/dicts/all")
    @ApiOperation(value = "获取所有枚举的值", notes = "获取所有枚举的值")
    public ResponseDto enumDictsAll(Integer structure) {
        if (structure == null) {
            structure = 1;
        }
        // 系统中所有的枚举类的包
        String[] packages = {
                "org.fzzn.core.model.enums",
                "com.hb.core.pojo.enums",
                "com.hb.core.pojo.project.proj.enums"
        };

        List<Class<?>> classList = CollUtil.list(false);

        for (String aPackage : packages) {
            Set<Class<?>> classes = ClassUtil.scanPackage(aPackage);
            classList.addAll(classes);
        }

        JSONObject data = JSONUtil.createObj();
        for (Class<?> clazz : classList) {
            String className = clazz.getName();

            int lastNameIndex = className.lastIndexOf('.');
            String suf = StrUtil.subSuf(className, lastNameIndex + 1);

            JSON values = Enums.listValues(className, structure);
            data.putOpt(suf, values);
        }
        return ResultUtil.msg(true, data);
    }
}
